/*
 * Wazuh Vulnerability Scanner - Unit Tests
 * Copyright (C) 2015, Wazuh Inc.
 * December 13, 2023.
 *
 * This program is free software; you can redistribute it
 * and/or modify it under the terms of the GNU General Public
 * License (version 2) as published by the FSF - Free Software
 * Foundation.
 */

#include "osDataCache_test.hpp"

TEST_F(OsDataCacheTest, TestSetAndGetSuccess)
{
    // Start fake server
    m_socketServer->listen(
        [&](const int fd, const char* data, uint32_t size, const char* dataHeader, uint32_t sizeHeader)
        {
            std::ignore = fd;
            std::ignore = dataHeader;
            std::ignore = sizeHeader;
            std::ignore = size;
            std::ignore = data;

            m_socketServer->send(fd, "err ", 4);
        });

    OsDataCache cache;
    std::string agentId {"1"};

    // Try to get value from empty cache
    EXPECT_THROW(cache.getOsData(agentId), OsDataException);

    // Set value in cache
    Os osData {.hostName = "hostName",
               .architecture = "architecture",
               .name = "name",
               .codeName = "codeName",
               .majorVersion = "majorVersion",
               .minorVersion = "minorVersion",
               .patch = "patch",
               .build = "build",
               .platform = "platform",
               .version = "version",
               .release = "release",
               .displayVersion = "displayVersion",
               .sysName = "sysName",
               .kernelVersion = "kernelVersion",
               .kernelRelease = "kernelRelease"};

    cache.setOsData(agentId, osData);

    // Get value from cache
    const auto osDataRetrieved = cache.getOsData(agentId);

    // Verify that the returned value is the same as the one set
    ASSERT_EQ(osDataRetrieved.hostName, osData.hostName);
    ASSERT_EQ(osDataRetrieved.architecture, osData.architecture);
    ASSERT_EQ(osDataRetrieved.name, osData.name);
    ASSERT_EQ(osDataRetrieved.codeName, osData.codeName);
    ASSERT_EQ(osDataRetrieved.majorVersion, osData.majorVersion);
    ASSERT_EQ(osDataRetrieved.minorVersion, osData.minorVersion);
    ASSERT_EQ(osDataRetrieved.patch, osData.patch);
    ASSERT_EQ(osDataRetrieved.build, osData.build);
    ASSERT_EQ(osDataRetrieved.platform, osData.platform);
    ASSERT_EQ(osDataRetrieved.version, osData.version);
    ASSERT_EQ(osDataRetrieved.release, osData.release);
    ASSERT_EQ(osDataRetrieved.displayVersion, osData.displayVersion);
    ASSERT_EQ(osDataRetrieved.sysName, osData.sysName);
    ASSERT_EQ(osDataRetrieved.kernelVersion, osData.kernelVersion);
    ASSERT_EQ(osDataRetrieved.kernelRelease, osData.kernelRelease);
}

TEST_F(OsDataCacheTest, TestDbQuery)
{
    // Create fake response
    nlohmann::json response;
    response["hostname"] = "hostName";
    response["architecture"] = "architecture";
    response["os_name"] = "name";
    response["os_codename"] = "codeName";
    response["os_major"] = "majorVersion";
    response["os_minor"] = "minorVersion";
    response["os_patch"] = "patch";
    response["os_build"] = "build";
    response["os_platform"] = "platform";
    response["os_version"] = "version";
    response["os_release"] = "release";
    response["os_display_version"] = "displayVersion";
    response["sysname"] = "sysName";
    response["version"] = "kernelVersion";
    response["release"] = "kernelRelease";

    std::string responseString = response.dump();
    std::string finalResponse = "ok ";
    finalResponse.append(responseString);

    // Start fake server
    m_socketServer->listen(
        [&](const int fd, const char* data, uint32_t size, const char* dataHeader, uint32_t sizeHeader)
        {
            std::ignore = dataHeader;
            std::ignore = sizeHeader;
            std::ignore = size;
            std::ignore = data;

            m_socketServer->send(fd, finalResponse.c_str(), finalResponse.size());
        });

    OsDataCache cache;
    std::string agentId {"1"};

    // Get value from cache
    auto osDataRetrieved = cache.getOsData(agentId);

    // Verify that the returned value is the one returned by the server
    ASSERT_EQ(osDataRetrieved.hostName, "hostName");
    ASSERT_EQ(osDataRetrieved.architecture, "architecture");
    ASSERT_EQ(osDataRetrieved.name, "name");
    ASSERT_EQ(osDataRetrieved.codeName, "codeName");
    ASSERT_EQ(osDataRetrieved.majorVersion, "majorVersion");
    ASSERT_EQ(osDataRetrieved.minorVersion, "minorVersion");
    ASSERT_EQ(osDataRetrieved.patch, "patch");
    ASSERT_EQ(osDataRetrieved.build, "build");
    ASSERT_EQ(osDataRetrieved.platform, "platform");
    ASSERT_EQ(osDataRetrieved.version, "version");
    ASSERT_EQ(osDataRetrieved.release, "release");
    ASSERT_EQ(osDataRetrieved.displayVersion, "displayVersion");
    ASSERT_EQ(osDataRetrieved.sysName, "sysName");
    ASSERT_EQ(osDataRetrieved.kernelVersion, "kernelVersion");
    ASSERT_EQ(osDataRetrieved.kernelRelease, "kernelRelease");
}
